#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

#include <assert.h>
#include <string.h>


namespace Yan
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;

	vector()
		:_start(nullptr)
		,_finish(nullptr)
		,_endofstorage(nullptr)
	{}

	vector(int  n, const T& val = T()) //如果是  size_t  n ,我们生成对象v2时，会调用我们写的区间构造函数。因为size_t 和 int 不匹配
		: _start(new T[n])
	{//memset(_start, val, sizeof(T)*n);
	// memset() 按照一个字节赋值，如果是int类型的，假设 memset 了1个元素值为1，最后结果是 0x 01 01 01 01(正确应该是0x01) 
	//所以需要使用别的方法
		for (int  i = 0; i < n; ++i)
		{
			//*(_start + i) = val;
			_start[i] = val;
		}
		_finish = _start + n;
		_endofstorage = _finish;
	}

	template<class Iterator>
	vector(Iterator first, Iterator last)
	{
		// size_t n = last - first;  //注意：一定不能减
		Iterator it = first;
		size_t n = 0;
		while (it != last)
		{
			n++;
			++it;
		}
	

		_start = new T[n];
		_finish = _start;
		while (first != last)
		{
			*_finish++ = *first++;
			// _finish++;
			// first++;
		}
		_endofstorage = _finish;
	}


	vector(const vector<T>& v)
		:_start(new T[v.size()])
	{
		int n = v.size();
		for (int i = 0; i < n; ++i)
		{
			_start[i] = v[i]; //v[i]此时调用自己写的函数，返回_start[index]
		}
		_finish = _start + n;
		_endofstorage = _finish;
	}



	vector<T>& operator=(vector<T> v)
	{
		swap(v);
		return *this;
	}

	~vector()
	{
		if (_start)
		{
			delete[] _start;
			_start = _finish = _endofstorage = nullptr;
		}
	}


	
	/////////////////////////////////////////////////
    // 迭代器

	iterator begin()
	{
		return _start;
	}

	iterator end()
	{
		return _finish;
	}
	iterator rbegin()
	{
		return end();
	}

	iterator rend()
	{
		return  begin();
	}
	/////////////////////////////////////////////////
	////////////////////////////////////////////////////
		// 容量

	size_t size()const
	{
		return _finish - _start;
	}
	size_t capacity()const
	{
		return _endofstorage - _start;
	}

	bool empty()const
	{
		return _start == _finish;
	}

	void resize(size_t newsize, const T& val = T())
	{
		size_t oldsize = size();
		if (newsize > oldsize)
		{
			size_t oldcap = capacity();
			if (newsize > oldcap)
				reserve(newsize);

			for (size_t i = oldsize; i < newsize; ++i)
			{
				_start[i] = val;
			}
		}

		_finish = _start + newsize;
	}

	void reserve(size_t newcap)
	{
		size_t oldcap = capacity();
		size_t count = size();
		if (newcap > oldcap)
		{
			// 1. 申请新空间
			T* temp = new T[newcap];

			if (_start)  // 对象扩容，里面有  内容  才实现接下来的操作
			{
				// 2. 拷贝元素
				// 浅拷贝
				// memcpy(temp, _start, sizeof(T)*count);

				for (size_t i = 0; i < count; ++i)
				{
					temp[i] = _start[i];
				}

				// 3. 释放旧空间
				delete[] _start;
			}

			_start = temp;
			_finish = _start + count;
			_endofstorage = _start + newcap;
		}
	}





	////////////////////////////////////////////////
	// 元素访问
	T& front()
	{
		return _start[0];
	}
	const T& front()const
	{
		return _start[0];
	}
	T& back()
	{
		return *(_finish-1);
	}
	const T& back()const
	{
		return *(_finish - 1);
	}


	T& operator[](size_t index)
	{
		assert(index < size());
		return _start[index];
	}

	const T& operator[](size_t index)const
	{
		assert(index < size());
		return _start[index];
	}

	//////////////////////////////////////////
	// 修改
	void push_back(const T& value)
	{
		if (_finish == _endofstorage)
		{
			reserve(size() * 2 +3); //如果此处不+3，那么到扩容函数里面去不会申请空间，下面的解引用就会出现问题
		}

		*_finish = value;
		++_finish;
	}

	void pop_back()
	{
		if (empty())
			return;

		--_finish;
	}

	iterator insert(iterator pos, const T& value)
	{
		

		if (pos < _start || pos > _finish)
			return end();

		if (_finish == _endofstorage)
		{
			iterator ret = begin(); //记录一下pos在容器中的相对位置，开辟新空间之后，重新给pos赋值,避免迭代器失效问题
			int n = 0;
			while (ret != pos)
			{
				n++;
				ret++;
			}
			reserve(2 * size());
			pos = begin() + n;
		}
			
		// 将pos及其后续所有的元素整体往后搬移
		iterator it = _finish;
		while (it != pos)
		{
			*it = *(it - 1);
			--it;
		}

		*pos = value;
		++_finish;
		return pos;
	}

	iterator erase(iterator pos)
	{
		if (pos < _start || pos >= _finish)
			return end();

		iterator it = pos + 1;
		while (it != _finish)
		{
			*(it - 1) = *it;
			++it;
		}

		--_finish;
		return pos;
	}

	void clear()
	{
		_finish = _start;
	}


	void swap(vector<T>& v)
	{
		std::swap(_start, v._start);
		std::swap(_finish, v._finish);
		std::swap(_endofstorage, v._endofstorage);
	}


	private:
		iterator _start;
		iterator _finish;
		iterator _endofstorage;

	};
}

void TestVector1()
{
	Yan::vector<int> v1;

	// int  int
	Yan::vector<int> v2(10, 5);
	for (size_t i = 0; i < v2.size(); ++i)
		cout << v2[i] << " ";
	cout << endl;

	int array[] = { 1, 2, 3, 4, 5 };
	Yan::vector<int> v3(array, array + 3);//左闭右开
	for (auto e : v3)
		cout << e << " ";
	cout << endl;

	Yan::vector<int> v4(v3);
	auto it = v4.begin();
	while (it != v4.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}


void TestVector2()
{
	Yan::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);

	cout << v.size() << endl;
	cout << v.capacity() << endl;

	for (auto e : v)
		cout << e << " ";
	cout << endl;

	v.push_back(4);
	cout << v.size() << endl;
	cout << v.capacity() << endl;

	for (auto e : v)
		cout << e << " ";
	cout << endl;

	cout << v.front() << endl;
	cout << v.back() << endl;

	v.pop_back();
	cout << v.front() << endl;
	cout << v.back() << endl;
}

void TestVector3()
{
	Yan::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);

	for (auto e : v)
		cout << e << " ";
	cout << endl;

	v.insert(std::find(v.begin(), v.end(), 2), 66);
	v.insert(std::find(v.begin(), v.end(), 2), 66);
	v.insert(std::find(v.begin(), v.end(), 2), 66);
	v.insert(std::find(v.begin(), v.end(), 2), 66);


	for (auto e : v)
		cout << e << " ";
	cout << endl;

	v.insert(v.begin() + 2, 22);

	for (auto e : v)
		cout << e << " ";
	cout << endl;

	auto it = v.begin();
	while (it != v.end())
	{
		it = v.erase(it);
		++it;
	}
}


void TestVector4()
{
	Yan::vector<int> v(10, 5);
	for (auto e : v)
		cout << e << " ";
	cout << endl;
	cout << "size=" << v.size() << endl;
	cout << "capacity=" << v.capacity() << endl;

	v.resize(20, 8);
	for (auto e : v)
		cout << e << " ";
	cout << endl;
	cout << "size=" << v.size() << endl;
	cout << "capacity=" << v.capacity() << endl;

	v.resize(30, 6);
	for (auto e : v)
		cout << e << " ";
	cout << endl;
	cout << "size=" << v.size() << endl;
	cout << "capacity=" << v.capacity() << endl;

	v.resize(10);
	for (auto e : v)
		cout << e << " ";
	cout << endl;
	cout << "size=" << v.size() << endl;
	cout << "capacity=" << v.capacity() << endl;

	v.resize(15, 0);
	for (auto e : v)
		cout << e << " ";
	cout << endl;
	cout << "size=" << v.size() << endl;
	cout << "capacity=" << v.capacity() << endl;
}



#include <list>

class String
{
public:
	String(const char* str = "")
	{
		if (nullptr == str)
			str = "";

		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}

	String(const String& s)
		: _str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}

	String& operator=(const String& s)
	{
		if (this != &s)
		{
			char* temp = new char[strlen(s._str) + 1];
			strcpy(temp, s._str);
			delete[] _str;
			_str = temp;
		}

		return *this;
	}

	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
private:
	char* _str;
};

#include<vector>

void Teststdvector()
{
	vector<String> v;
	v.push_back("1111");
	v.push_back("1111");
	v.push_back("2222");
	v.push_back("3333");
}


void Testbitevector()
{
	Yan::vector<String> v;
	v.push_back("1111");
	v.push_back("2222");
	v.push_back("3333");
	v.push_back("4444");
}

int main()
{
	//int array[10];
	//memset(array, 5, sizeof(array));

	//int array[] = { 1, 2, 3, 4 };
	//vector<int> v1(array, array + sizeof(array) / sizeof(array[0]));

	//list<int> L{ 1, 2, 3 };
	//vector<int> v2(L.begin(), L.end());

	 //TestVector1();
	 //TestVector2();
	 TestVector3();
	//TestVector4();
	// Teststdvector();

//	Testbitevector();
	_CrtDumpMemoryLeaks();
	return 0;
}


